global u8 coldpeakszone.isFrozen
global u8 coldpeakszone.is2PFrozen
global u8 coldpeakszone.breakingOutAnimTimer
global u8 coldpeakszone.breakingOutAnimTimerP2

//# post-update-hook
function void PostFrameUpdate()
{
	if global.game_mode != 0x0c || u8[0xffffb000 + 0x05] >= base_state.DIED
	{
		coldpeakszone.isFrozen = 0
		coldpeakszone.is2PFrozen = 0
		coldpeakszone.breakingOutAnimTimer = 0
		coldpeakszone.breakingOutAnimTimerP2 = 0
	}
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0 && global.zone_act == 0x0500
	{
		System.setGlobalVariableValueByName("UniqueFrozenSprites.isFrozen", coldpeakszone.isFrozen)
		System.setGlobalVariableValueByName("UniqueFrozenSprites.is2PFrozen", coldpeakszone.is2PFrozen)
		
		if player1.control_override == 0x00 || !(u8[0xffffb000 + 0x20] == char.state.GOT_HURT && u8[0xffffb000 + 0x2e] == control_flag.DISABLE_ANIMATION)
			coldpeakszone.isFrozen = 0
		
		if player2.control_override == 0x00 || !(u8[0xffffb04a + 0x20] == char.state.GOT_HURT && u8[0xffffb04a + 0x2e] == control_flag.DISABLE_ANIMATION)
			coldpeakszone.is2PFrozen = 0
	}
	base.PostFrameUpdate()
}

function void playSound(u8 soundId)
{
	if (soundId == 0x6e && customZoneSelect.alternateZoneSet == 0 && global.zone_act == 0x0500 && objA0.update_address == 0x08b384)
	{
		Audio.playAudio("coldpeakszone.Shatter")

		D4.u16 = 0x288
		if (objA0.subtype2c == 1)
		{
			for (s16 i = 5; i > 0; --i)
			{
				objA1.update_address = 0x01a64a
				objA1.render_flags = (render_flag.WORLD | render_flag.VISIBLE)
				objA1.base_state += 2
				objA1.box_size.x = 8
			#if STANDALONE
				objA1.box_size.y = 8
			#endif
				objA1.sprite_priority = 0x180
				objA1.sprite_attributes = (sprite_attribute.PRIORITY | sprite_attribute.PALETTE.LINE1 | 0x06bc)
				objA1.mapping_offset = 0x01a99a
				objA1.position.x.u16 = objA0.position.x.u16
				objA1.position.y.u16 = objA0.position.y.u16
				objA1.hitbox_extends.x = 8
				objA1.hitbox_extends.y = 8
				objA1.collision_attributes = (collision.flag.ITEM | collision.size.6x6)

				spilled_rings.speed = 0xff
				if (D4.s16 >= 0)
				{
					// Entered only for every second ring (the others use x-mirrored directions)
					u8 angle = D4.u8
					u8 shift = D4.u16 >> 8
					D2.s16 = lookupSin(angle) << shift
					D3.s16 = lookupCos(angle) << shift
					D3.s16 /= 2

					// Go on with next angle (and possibly switch to a lower shift)
					if (D4.u8 < 0xf0)
					{
						D4.u8 += 0x10
					}
					else
					{
						D4.u16 -= 0x170
						if (D4.s16 < 0)
						{
							D4.s16 = 0x288
						}
					}
				}
				objA1.velocity.x = D2.u16
				objA1.velocity.y = D3.u16
				D2.s16 = -D2.s16
				D4.s16 = -D4.s16

				// Next ring
				if (!allocDynamicObjectAfterA0())
					break
			}
		}
		return
	}
	base.playSound(soundId)
}

//# translated(0x0117da) end(0x0118ba)
//# translated(0x015002) end(0x0150d8)
//# translated(0x017710) end(0x0177e8)
function bool Character.CheckStartJump()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0 && global.zone_act == 0x0500 && char.state == char.state.GOT_HURT && u8[A0 + 0x2e] == control_flag.DISABLE_ANIMATION
		return false

	return base.Character.CheckStartJump()
}

//# address-hook(0x08a9e0)
function void fn08a9e0()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if (u8[A4 + 0x2e] == 0)
		{
			if (u8[A4 + 0x34] < 60 && u8[A4 + 0x05] < base_state.HURT) && ((coldpeakszone.isFrozen == 0 && A4 == 0xffffb000) || (coldpeakszone.is2PFrozen == 0 && A4 == 0xffffb04a))
			{
				Audio.playAudio(0x80)
				u16[A4 + 0x1c] = 0
				u8[A4 + 0x2a] |= 0x02
				if !(u8[0xffffb04a + 0x38] == 1 && u8[0xffffE654] != 0)
					u8[A4 + 0x2e] = (control_flag.DISABLE_ANIMATION)
				if u8[A4 + 0x38] == 0
				{
					u8[A4 + 0x20] = char.state.GOT_HURT
					u8[A4 + 0x22] = 0x8d
				}
				else if u8[A4 + 0x38] == 1
				{
					u8[A4 + 0x20] = char.state.GOT_HURT
					u8[A4 + 0x22] = 0x8a
				}
				else
				{
					u8[A4 + 0x20] = char.state.GOT_HURT
					u8[A4 + 0x22] = 0x8d
				}
				u8[A4 + 0x3d] = 0

				if (abs(s16[A4 + 0x18]) < 0x200)
				{
					if (s16[A4 + 0x18] < 0)
						s16[A4 + 0x18] = -0x200
					else s16[A4 + 0x18] = 0x200
				}

				if (abs(s16[A4 + 0x1c]) < 0x200)
				{
					if (s16[A4 + 0x1c] < 0)
						s16[A4 + 0x1c] = -0x200
					else s16[A4 + 0x1c] = 0x200
				}

				D4 = D0
				{
					// "spawnChildObjects(0x08aae2)" replaced by:
					spawnChildObject(0x08a7ae, 0x00, 0, 0)
				}
				D0 = D4
				u16[A1 + 0x44] = A4.u16
			}
		}
		if u8[A4 + 0x20] == char.state.GOT_HURT || u8[A4 + 0x20] == char.state.DIED
		{
			if A4 == 0xffffb04a
				coldpeakszone.is2PFrozen = 1
			else coldpeakszone.isFrozen = 1
		}
	}
	else base.fn08a9e0()
}

//# address-hook(0x08a778) end(0x08a7a0)
function void fn08a778()
{
	base.fn08a778()
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if (abs(objA0.position.x.u16 - u16[0xffb010]) > getScreenWidth())
			UnloadObject()
	}
}

//# address-hook(0x08a748) end(0x08a758)
function void fn08a748()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		objA0.update_address = 0x08a75c
		setupObjectAttributesFull(0x08aa96)
	}
	else base.fn08a748()
}

//# address-hook(0x08a78c)
function void fn08a78c()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		objA0.update_address = 0x08a7a2
		objA0.countdown_value = 0
	}
	else base.fn08a78c()
}

//# address-hook(0x08a7a2) end(0x08a7aa)
function void fn08a7a2()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		CheckDistanceToPlayers()
		if !(D2.u16 < 0xa0)
			UnloadObject()
		A1 = 0x08aa30
		fn08a9c6()
	}
	else base.fn08a7a2()
}

//# address-hook(0x08a656) end(0x08a67a)
function void Freezer.Update()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		CheckDistanceToPlayers()
		if (D2.u16 < 0xa0)
		{
			objA0.update_address = 0x08a67e
			objA0.countdown_value = 0
			u16[A0 + 0x30] = 0
			objA0.value39 = 0
			playSound(0x7f)
		}
		Enemy.DrawOrUnload()
	}
	else base.Freezer.Update()
}

//# address-hook(0x08a67e) end(0x08a6da)
function void fn08a67e()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if (objA0.subtype2c)
		{
			++objA0.countdown_value

			objA0.velocity.y -= 16

			if (objA0.render_flags & render_flag.VISIBLE) == 0 || objA0.countdown_value == 60
				UnloadObject()

			UpdateMovementStraightSimple()
		}
		else
		{
			CheckDistanceToPlayers()
			if (D2.u16 < 0xa0)
			{
				--u16[A0 + 0x30]
				if (s16[A0 + 0x30] < 0)
				{
					D0 = objA0.value39 ^ 0x02
					objA0.value39 = D0.u8
					u16[A0 + 0x30] = u16[0x08a6de + D0.u16]

					call 0x08a6ee
				}

				if (objA0.flags38 & 0x02)
				{
					--objA0.countdown_value
					if (objA0.countdown_value < 0)
					{
						objA0.countdown_value = 0x02
						fn08a708()
					}

					Freezer.spawnIceWind()
				}
			}
			else
			{
				objA0.update_address = addressof(Freezer.Update)
				objA0.flags38 &= ~0x02
				playSound(0xe4)
			}
		}
		DrawObject()
	}
	else base.fn08a67e()
}

//# address-hook(0x08a9c6) end(0x08aa2e)
function void fn08a9c6()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		D3.u16 = objA0.position.x.u16 + u16[(A1+=2)-2] - 0x10
		D5.u16 = D3.u16 + u16[(A1+=2)-2] + 0x10
		D4.u16 = objA0.position.y.u16 + u16[(A1+=2)-2]
		D6.u16 = D4.u16 + u16[(A1+=2)-2] + 0x30

		D0 = 0
		A2 = 0xffffb04a
		D1.u16 = u16[A2 + 0x10]
		D2.u16 = u16[A2 + 0x14]
		fn08592c()

		D0 <<= 16
		A2 = 0xffffb000
		D1.u16 = u16[A2 + 0x10]
		D2.u16 = u16[A2 + 0x14]
		fn08592c()

		if (D0.u16 != 0)
		{
			A4 = 0xffff0000 + D0.u16
			fn08a9e0()
		}

		D0 = (D0 >> 16)
		if (D0.u16 != 0)
		{
			A4 = 0xffff0000 + D0.u16
			fn08a9e0()
		}
	}
	base.fn08a9c6()
}

function void Freezer.spawnIceWind()
{
	if (global.framecounter % 2 == 0)
	{
		if (allocDynamicObjectStd())
		{
			objA1.update_address = 0x08a67e
			objA1.position.x.u16 = objA0.position.x.u16
			objA1.position.y.u16 = objA0.position.y.u16 + 16

			objA1.velocity.x = max(0x80, System.rand() % 0x100)
			objA1.velocity.y = max(0x280, System.rand() % 0x200)
			if (global.framecounter % 8 == 0)
				objA1.velocity.x /= 3
			else if (global.framecounter % 4 < 2)
				objA1.velocity.x = -objA1.velocity.x

			objA1.render_flags = (render_flag.WORLD | render_flag.VISIBLE)

			objA1.box_size.x = 0x40
			objA1.box_size.y = 0x40

			objA1.subtype2c = 1
		}
	}
}

//# address-hook(0x08a708) end(0x08a718)
function void fn08a708()
{
	A2 = (objA0.render_flags & render_flag.FLIP_Y) ? 0x08aaca : 0x08aac2
	SpawnChildObjects()
}

function u32 Game.getSetting(u32 settingId)
{
	if settingId == SETTING_PLAYER2_OFFSCREEN && tails.control_counter <= 30 && global.zone_act == 0x0500 && customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
		return false
	return base.Game.getSetting(settingId)
}

//# address-hook(0x08a84c)
function void fn08a84c()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		A1 = 0xffff0000 + u16[A0 + 0x44]
		D0.u16 = objA0.position.x.u16
		D1.u16 = objA0.position.y.u16
		if (u8[A1 + 0x38] == CHARACTER_KNUCKLES)
		{
			D2 = (objA1.render_flags & render_flag.FLIP_X) ? 4 : -4
			D0.u16 += D2.u16
			D1.u16 += 2
		}
		
		objA0.position.x.u16 = objA1.position.x.u16
		objA0.position.y.u16 = objA1.position.y.u16
		
		if (A1 == 0xffffb000 && control.pad1.pressed & CONTROL_ABC) || (A1 == 0xffffb04a && control.pad2.pressed & CONTROL_ABC)
		{
			if (A1 == 0xffffb04a && control.pad2.pressed & CONTROL_ABC)
				coldpeakszone.breakingOutAnimTimerP2 = 4
			if objA0.countdown_value > 0x1f
				Audio.playAudio("coldpeakszone.Struggle")
			objA0.countdown_value -= 0x1f
		}
		u8[A1 + 0x2a] |= (char.flag.CONTROL_LOCK | char.flag.ROLLING)
		u8[A1 + 0x2e] = (control_flag.DISABLE_ANIMATION)
		u8[A1 + 0x40] = 0x00
		if A1 == 0xffffb04a
		{
			control.player2 = CONTROL_DOWN
			control.tails = CONTROL_DOWN
			player2.control_override = 0xff
		}
		else
		{
			control.player1 = CONTROL_DOWN
			player1.control_override = 0xff
		}
		if u8[A1 + 0x38] == 0
		{
			u8[A1 + 0x20] = char.state.GOT_HURT
			u8[A1 + 0x22] = 0x8d
		}
		else if u8[A1 + 0x38] == 1
		{
			u8[A1 + 0x20] = char.state.GOT_HURT
			u8[A1 + 0x22] = 0x8a
		}
		else
		{
			u8[A1 + 0x20] = char.state.GOT_HURT
			u8[A1 + 0x22] = 0x8d
		}
		
		if coldpeakszone.isFrozen
		{
			if (u8[A1 + 0x2a] & char.flag.FACING_LEFT) && !(u8[A1 + 0x04] & render_flag.FLIP_X)
				u8[A1 + 0x2a] &= ~char.flag.FACING_LEFT
			else if !(u8[A1 + 0x2a] & char.flag.FACING_LEFT) && (u8[A1 + 0x04] & render_flag.FLIP_X)
				u8[A1 + 0x2a] |= char.flag.FACING_LEFT
		}
		
		if (objA0.countdown_value >= 0)
		{
			if A1 == 0xffffb04a
			{
				// When Tails is frozen, he will try to free himself if he isn't already controlled by Player 2
				if tails.control_counter == 0
					tails.control_counter = 30
				--tails.control_counter
				if coldpeakszone.is2PFrozen
				{
					if tails.control_counter == 0
					{
						control.pad2 = 0x2020
						if objA0.countdown_value > 0x1f
							Audio.playAudio("coldpeakszone.Struggle")
						objA0.countdown_value -= 0x1f
						tails.control_counter = 30
					}
					else
					{
						control.pad2 = 0x0000
					}
				}
			}
			fn08aa38()
			if (_equal())
			{
				DrawObject()
				return
			}
		}
		else
		{
			A1 = 0xffff0000 + u16[A0 + 0x44]
			A2 = A0
			A0 = A1
			if A0 == 0xffffb04a
				coldpeakszone.is2PFrozen = 0
			else coldpeakszone.isFrozen = 0
			objA0.velocity.y = -0x480
			objA0.state = char.state.ROLLING
			u8[A0 + 0x2a] |= 0x02
			u8[A0 + 0x2e] = 0
			u8[A0 + 0x34] = 0x40
			Audio.playAudio("coldpeakszone.Shatter")
			if A0 == 0xffffb04a
				player2.control_override = 0x00
			else player1.control_override = 0x00
			A0 = A2
		}

		A1 = 0xffff0000 + u16[A0 + 0x44]
		u8[A1 + 0x2a] |= 0x02
		u8[A1 + 0x2e] = 0
		u8[A1 + 0x34] = 0x78

		// Spawn broken ice block chunks
		// "spawnChildObjects(0x08aaea)" replaced by:
		spawnChildObject(0x08a8dc, 0x00, -12, -8)
		spawnChildObject(0x08a8dc, 0x02, -4, -8)
		spawnChildObject(0x08a8dc, 0x04, 4, -8)
		spawnChildObject(0x08a8dc, 0x06, 12, -8)
		spawnChildObject(0x08a8dc, 0x08, -12, 0)
		spawnChildObject(0x08a8dc, 0x0a, -4, 0)
		spawnChildObject(0x08a8dc, 0x0c, 4, 0)
		spawnChildObject(0x08a8dc, 0x0e, 12, 0)
		spawnChildObject(0x08a8dc, 0x10, -12, 8)
		spawnChildObject(0x08a8dc, 0x12, -4, 8)
		spawnChildObject(0x08a8dc, 0x14, 4, 8)
		spawnChildObject(0x08a8dc, 0x16, 12, 8)

		UnloadObject()
	}
	else base.fn08a84c()
}

//# address-hook(0x08aa38) end(0x08aa8c)
function void fn08aa38()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		A3 = 0xffffb000
		if (A3.u16 == u16[A0 + 0x44])
		{
			A3 = 0xffffb04a
		}

		_setZeroFlagByValue(0)
		if (s16[A3 + 0x1a] < 0)
			return

		if (u8[A3 + 0x20] != char.state.ROLLING && u8[A3 + 0x20] != char.state.SPINDASH)
			return

		A1 = 0x08aa8e
		fn0858f8()
		if (D0 == 0)
			return

		if (D0.u16 != 0)
		{
			player2.control_override = 0x00
			if coldpeakszone.is2PFrozen == 1
			{
				Audio.playAudio("coldpeakszone.Shatter")
				s16[0xffffb000 + 0x1a] = -0x480
				u8[0xffffb000 + 0x20] = char.state.ROLLING
				u8[0xffffb000 + 0x2a] |= 0x02
				u8[0xffffb000 + 0x2e] = 0
				u8[0xffffb000 + 0x34] = 0x40
			}
			coldpeakszone.is2PFrozen = 0
			A4 = 0xffff0000 + D0.u16
			if (u8[A4 + 0x2e] == 0)
			{
				s16[A3 + 0x1a] = -s16[A3 + 0x1a]
				_setZeroFlagByValue(1)
				return
			}
		}

		D0 = (D0 << 16) + (D0 >> 16)
		if (D0.u16 != 0)
		{
			player1.control_override = 0x00
			if coldpeakszone.isFrozen == 1
			{
				Audio.playAudio("coldpeakszone.Shatter")
				s16[0xffffb000 + 0x1a] = -0x480
				u8[0xffffb000 + 0x20] = char.state.ROLLING
				u8[0xffffb000 + 0x2a] |= 0x02
				u8[0xffffb000 + 0x2e] = 0
				u8[0xffffb000 + 0x34] = 0x40
			}
			coldpeakszone.isFrozen = 0
			A4 = 0xffff0000 + D0.u16
			if (u8[A4 + 0x2e] == 0)
			{
				s16[A3 + 0x1a] = -s16[A3 + 0x1a]
				_setZeroFlagByValue(1)
			}
		}
	}
	else base.fn08aa38()
}

function u64 Standalone.getModdedAnimationSpriteKey(u8 character, u16 animationSpriteEx)
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if character == CHARACTER_TAILS && getMainCharacter() != CHARACTER_TAILS
		{
			if control.pad2.pressed & CONTROL_ABC
			{
				coldpeakszone.breakingOutAnimTimerP2 = 4
			}
			
			if coldpeakszone.breakingOutAnimTimerP2
			{
				coldpeakszone.breakingOutAnimTimerP2 -= 1
			}
		}
		else
		{
			if control.pad1.pressed & CONTROL_ABC
			{
				coldpeakszone.breakingOutAnimTimer = 4
			}
			
			if coldpeakszone.breakingOutAnimTimer
			{
				coldpeakszone.breakingOutAnimTimer -= 1
			}
		}
		if character == CHARACTER_SONIC
		{
			if u8[0xffffb000 + 0x20] != char.state.GOT_HURT
				coldpeakszone.isFrozen = 0
		}
		else if character == CHARACTER_TAILS
		{	
			if getMainCharacter() == CHARACTER_TAILS //tails why do you gotta be so complicated
			{
				if u8[0xffffb000 + 0x20] != char.state.GOT_HURT && u8[0xffffb000 + 0x20] != char.state.DIED
					coldpeakszone.isFrozen = 0
			}
			else
			{
				if u8[0xffffb04a + 0x20] != char.state.GOT_HURT
					coldpeakszone.is2PFrozen = 0
			}
		}
		else if character == CHARACTER_KNUCKLES
		{
			if u8[0xffffb000 + 0x20] != char.state.GOT_HURT
				coldpeakszone.isFrozen = 0
		}
	}
	return base.Standalone.getModdedAnimationSpriteKey(character, animationSpriteEx)
}

//# address-hook(0x010294) end(0x010364)
function void Character.GettingHurt()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if (A0 == 0xffffb000 && !coldpeakszone.isFrozen) || (A0 == 0xffffb04a && !coldpeakszone.is2PFrozen)
			base.Character.GettingHurt()
	}
	else base.Character.GettingHurt()
}

function bool Standalone.onWriteToSpriteTable(s16 px, s16 py, u16 renderQueue)
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0
	{
		if (((objA0.update_address == 0x08a84c) || (objA0.update_address == 0x08a80c)))
		{
			if objA0.countdown_value == 0x7f
			{
				SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x00", objA0.position.x.u16, (char.hitbox_extends.y == char.hitbox.y.UPRIGHT) ? objA0.position.y.u16 : objA0.position.y.u16 - 4, 0x9ffe)
				iceblock.setFlags(0x20)
				iceblock.setPaletteOffset(0x20)
				return true
			}
			else if (objA0.countdown_value >= 0x5f)
			{
				SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x01", objA0.position.x.u16, (char.hitbox_extends.y == char.hitbox.y.UPRIGHT) ? objA0.position.y.u16 : objA0.position.y.u16 - 4, 0x9ffe)
				iceblock.setFlags(0x20)
				iceblock.setPaletteOffset(0x20)
				return true
			}
			else if (objA0.countdown_value >= 0x3f)
			{
				SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x02", objA0.position.x.u16, (char.hitbox_extends.y == char.hitbox.y.UPRIGHT) ? objA0.position.y.u16 : objA0.position.y.u16 - 4, 0x9ffe)
				iceblock.setFlags(0x20)
				iceblock.setPaletteOffset(0x20)
				return true
			}
			else if (objA0.countdown_value >= 0x1f)
			{
				SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x03", objA0.position.x.u16, (char.hitbox_extends.y == char.hitbox.y.UPRIGHT) ? objA0.position.y.u16 : objA0.position.y.u16 - 4, 0x9ffe)
				iceblock.setFlags(0x20)
				iceblock.setPaletteOffset(0x20)
				return true
			}
			else
			{
				SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x04", objA0.position.x.u16, (char.hitbox_extends.y == char.hitbox.y.UPRIGHT) ? objA0.position.y.u16 : objA0.position.y.u16 - 4, 0x9ffe)
				iceblock.setFlags(0x20)
				iceblock.setPaletteOffset(0x20)
				return true
			}
		}
		if objA0.update_address == 0x08b384
		{
			if objA0.subtype2c == 1
			{
				Renderer.drawSprite("ring_02", px-10, py+5, 0, 0, 0x9ffc)
				Renderer.drawSprite("ring_02", px-5, py+1, 0, 0, 0x9ffc)
				Renderer.drawSprite("ring_02", px, py-1, 0, 0, 0x9ffc)
				Renderer.drawSprite("ring_02", px+5, py+1, 0, 0, 0x9ffc)
				Renderer.drawSprite("ring_02", px+10, py+5, 0, 0, 0x9ffc)
			}
			SpriteHandle iceblock = Renderer.addSpriteHandle("coldpeakszone_iceblock_0x05", px, py, 0x9ffe)
			iceblock.setPaletteOffset(0x20)
			return true
		}
		if objA0.mapping_offset == 0x3639c0 && objA0.subtype2c == 1
		{
			SpriteHandle icechunk = Renderer.addSpriteHandle("coldpeakszone_icechunk", px, py, 0x9ffe)
			icechunk.setPaletteOffset(0x20)
			return true
		}
		if (objA0.update_address == 0x08a67e && objA0.subtype2c)
		{
			SpriteHandle icewind = Renderer.addSpriteHandle(stringformat("coldpeakszone_icewind_%d", objA0.countdown_value / 15), px, py, 0x9ffe)
			icewind.setPaletteOffset(0x20)
			return true
		}
	}
	return base.Standalone.onWriteToSpriteTable(px, py, renderQueue)
}

//# address-hook(0x08a280) end(0x08a2dc)
function void fn08a280()
{
	if customZoneSelect.useAlternates == 1 && customZoneSelect.alternateZoneSet == 0 && objA0.subtype2c == 1
	{
		// Ground speed of player 1 before the collision
		s16 speed = s16[0xffffb000 + 0x1c]
		s16 xvelocity = s16[0xffffb000 + 0x18]
		
		D1 = 0x2b
		D2 = 0x40
		D3 = 0x70
		D4.u16 = objA0.position.x.u16
		fn01dc56()
		
		if coldpeakszone.isFrozen
		{
			D6 = (D6 << 16) + (D6 >> 16)
			D6.u16 &= 0x01
			if (D6.u16 != 0)
			{
				spawnChildObjects(0x08aaea)		// Wall fragments

				Object.TriggerUnloading()
				Audio.playAudio("coldpeakszone.Shatter")
				DrawOrUnloadObject()

				s16[0xffffb000 + 0x18] = xvelocity
				s16[0xffffb000 + 0x1c] = speed
				u8[0xffffb000 + 0x2a] &= ~char.flag.PUSHING
				return
			}
		}

		A1 = 0xffff0000 + u16[0xfffffaa4]
		if (objA1.update_address == 0x089f38)
		{
			D0.u16 = objA1.position.x.u16
			D1.u16 = objA1.position.y.u16 & level.height.bitmask
			D2.u16 = objA0.position.x.u16
			D3.u16 = objA0.position.y.u16

			A2 = 0x08a2fc
			D2.u16 += u16[A2]
			if (D0.u16 >= D2.u16)
			{
				D2.u16 += u16[A2+2]
				if (D0.u16 < D2.u16)
				{
					D3.u16 += u16[A2+4]
					if (D1.u16 >= D3.u16)
					{
						D3.u16 += u16[A2+6]
						if (D1.u16 < D3.u16)
						{
							fn08a2e2()
							return
						}
					}
				}
			}
		}
		
		DrawOrUnloadObject()
	}
	else base.fn08a280()
}
